module game
{
	/**
	 * 基础场景
	 * 实现消消乐场景的基本功能
	 * 场景内直接添加pop和grid
	 */
	export class BaseScene extends egret.DisplayObjectContainer
	{
		/**场景的格子地图 */
		private _map:Array<number>;
		/**默认泡泡数组 */
		private _default:Array<number>;
		private _col:number;
		private _row:number;
		/**场景名字 */
		private _name:string;
		/**pop类型数量，随机产生pop的时候需要 */
		private _types:number;

		private _gridArr:Array<Array<BaseGrid>>;
		private _touchRect:eui.Rect;
		private _popArr:Array<Array<BasePop>>;
		private _gridSp:egret.Sprite;
		private _popSp:egret.Sprite;

		public constructor()
		{
			super();
		}

		public init(map:Array<number>,row:number,col:number,name:string,pop:Array<number>,types:number):void
		{
			this._map = map;
			this._default = pop;
			this._row = row;
			this._col = col;
			this._name = name;
			this._types = types;

			this._gridArr = new Array<Array<BaseGrid>>();
			this._popArr = new Array<Array<BasePop>>();
			this._gridSp = new egret.Sprite();
			this.addChild(this._gridSp);
			this._popSp = new egret.Sprite();
			this.addChild(this._popSp);

			this._touchRect = new eui.Rect();
			this._touchRect.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.onTouch,this);
			this._touchRect.addEventListener(egret.TouchEvent.TOUCH_END,this.onTouch,this);
			this._touchRect.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE,this.onTouch,this);

			TweenManager.getInstance().addEventListener(TweenManager.TWEEN_COMPLETE,this.tweenComplete,this);

			this.build();
		}

		public changeMap(map:Array<number>):void
		{
			this.dispose();
			this._map = map;
			this.build();
		}

		private build():void
		{
			for(let i = 0;i < this._col;i++)
			{
				this._gridArr[i] = new Array<BaseGrid>();
				this._popArr[i] = new Array<BasePop>();

				for(let j = 0;j < this._row;j++)
				{
					let type = this._map[i + j*this._col];
					let popType = this._default[i + j*this._col];
					// if(!type)
						console.log("type:",type,i,j,i + j*this._col);
					// if(type > 0)
					// {
						let grid = new BaseGrid();
						grid.type = type;
						grid.isBlank = type == 0;
						this._gridSp.addChild(grid);
						grid.init();
						grid.x = i*40;
						grid.y = j*40;
						
						this._gridArr[i][j] = grid;
						let pop = PopPool.create();
						pop.type = popType;
						pop.isBlank = type == 0;
						this._popSp.addChild(pop);
						this.setPopPos(pop,i,j);
						
						// pop.curPt = egret.Point.create(i,j);
						// pop.x = i*40;
						// pop.y = j*40;
						// this._popArr[i][j] = pop;
					// }
					// else if(type == 0)
					// {
					// 	let grid = new PopGeneratorGrid();
					// 	grid.type = type;
					// 	this._gritSp.addChild(grid);
					// 	grid.init();
					// 	grid.x = i*40;
					// 	grid.y = j*40;
					// }
				}
			}

			this._touchRect.width = 40*this._col;
			this._touchRect.height = 40*this._row;
			this._touchRect.fillColor = 0;
			this._touchRect.alpha = 0.01;
			this.addChild(this._touchRect);
		}

		private _startX:number;
		private _startY:number;
		private _curGrid:BaseGrid;
		/**当前选中的pop */
		private _selectPop:BasePop;
		/**被交换的pop */
		private _exchangePop:BasePop;

		private onTouch(e:egret.TouchEvent):void
		{
			// console.warn('onTouch:',e.type);

			switch(e.type)
			{
				case egret.TouchEvent.TOUCH_BEGIN:
					if(this._curGrid){this._curGrid.select(false);}
					//记录起始位置
					this._startX = e.localX;
					this._startY = e.localY;
					this.checkStart();
					this._touchRect.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.onTouch,this);
					break;
				case egret.TouchEvent.TOUCH_MOVE:
					this.checkMove(e.localX,e.localY);
					break;
				case egret.TouchEvent.TOUCH_RELEASE_OUTSIDE:
				case egret.TouchEvent.TOUCH_END:
					this._touchRect.removeEventListener(egret.TouchEvent.TOUCH_MOVE,this.onTouch,this);
					break;
			}
		}

		/**检测起始点 */
		private checkStart():void
		{
			let posX = Math.floor(this._startX/40);
			let posY = Math.floor(this._startY/40);

			// console.log(posX,posY);

			let grid = this._gridArr[posX][posY];
			let pop = this._popArr[posX][posY];
			// console.warn(pop);
			// console.warn(this._popArr);
			// console.warn('posX:',posX,'posY',posY);
			if(grid && pop && !pop.isBlank)
			{
				grid.select(true);
				this._curGrid = grid;
				this._selectPop = pop;
			}
		}

		private checkMove(moveX:number,moveY:number):void
		{
			let posX = Math.floor(moveX/40);
			let posY = Math.floor(moveY/40);

			let grid = this._gridArr[posX][posY];
			let pop = this._popArr[posX][posY];

			// if(grid && grid != this._curGrid)
			{
				//交换位置
				if(pop && pop != this._selectPop && !pop.isBlank)
				{
					//检测必须是周边4个的pop
					//需要判断坐标
					let pt = pop.curPt;
					let spt = this._selectPop.curPt;
					if(pt.x != spt.x && pt.y != spt.y)//两个都不等，可能是对角线了，需要过滤掉
					{
						console.log('对角线不能移动...');
						console.log('pt.x,spt.x',pt.x,spt.x);
						console.log('pt.y,spt.y',pt.y,spt.y);
					}
					else
					{
						if(Math.abs(pt.x - spt.x) > 1 || Math.abs(pt.y - spt.y) > 1)
						{
							console.log('选择超出了距离...');
						}
						else
						{
							//需要修改数组位置
							this._popArr[pt.x][pt.y] = this._selectPop;
							this._popArr[spt.x][spt.y] = pop;
							this._exchangePop = pop;
							pop.tagPt = egret.Point.create(spt.x,spt.y);
							this._selectPop.tagPt = egret.Point.create(pt.x,pt.y);
							pop.move();
							this._selectPop.move();
							this._touchRect.enabled = false;
						}
					}
					this._touchRect.removeEventListener(egret.TouchEvent.TOUCH_MOVE,this.onTouch,this);
				}
			}
		}

		private tweenComplete():void
		{
			//检测是否还有可以消除的pop
			let check = PopRules.check(this._popArr);
			console.log('check.length:',check.length);
			if(check.length > 0)//大于0，有可以消除的
			{
				let types:Array<number> = [];
				//1.消除
				for(let i = check.length -1;i >= 0;i--)
				{
					let pop = this._popArr[check[i].x][check[i].y];
					if(pop)
					{
						types.push(pop.type);
						PopPool.store(pop);
						this._popArr[check[i].x][check[i].y] = null;
					}
				}
				this.dispatchEventWith(GameEvent.RemovePop,false,types);

				//2.填充
				if(this.checkFill())
				{
					//移动到指定位置
					this.moveAll();
				}
				else
				{
					//顶部pop被消除后，由于没有可以填充的，所以直接添加新的pop
					//为空白的区域创建新的pop
					if(this.createNewPop())
					{
						//移动到指定位置
						this.moveAll();
					}
				}
			}
			else
			{
				//回弹
				if(this._exchangePop && this._selectPop)
				{
					let pt = this._exchangePop.curPt;
					let spt = this._selectPop.curPt;
					this._popArr[pt.x][pt.y] = this._selectPop;
					this._popArr[spt.x][spt.y] = this._exchangePop;
					this._exchangePop.tagPt = egret.Point.create(spt.x,spt.y);
					this._selectPop.tagPt = egret.Point.create(pt.x,pt.y);
					this._exchangePop.move();
					this._selectPop.move();
				}
				else
				{
					//填充完毕，添加新的pop
					if(this.createNewPop())
					{
						this.moveAll();
					}
					else//如果没有，则这轮消除结束，开启touchEnable
					{
						this._touchRect.enabled = true;
					}
				}
			}

			if(this._exchangePop && check.length > 0)
			{
				this.dispatchEventWith(GameEvent.ReduceSteps,false,1);
			}
			this._selectPop = null;
			this._exchangePop = null;
			console.log('enabled:',this._touchRect.enabled);
		}

		/**pop重新排布 */
		private popReset():void
		{

		}

		/**
		 * 填充
		 * 
		 * 分两个步骤：1.将现有的pop移动到目标位置 2.生成新的pop，并移动到目标位置(检测消除)
		 * 
		 * 然后循环...
		 *  */
		private checkFill():boolean
		{
			//1.从数组的末尾遍历所有的pop
			//2.检测这个pop的下方是否有空位，检测到底位置
			//3.修改它应该移动到的位置
			//4.播放移动动画
			let result = false;
			let isBlank = false;
			for(let i = this._popArr.length - 1;i >= 0;i--)
			{
				let popCol = this._popArr[i];
				for(let j = popCol.length - 1;j >= 0;j--)
				{
					let pop = popCol[j];
					if(pop == null)//当前位置没有pop，必须从上面滑下来一个
					{
						// console.warn('x:',i,'y:',j);
						let n = 1;
						let next:BasePop;
						
						while(j - n >= 0)
						{
							next = popCol[j - n];
							if(next)
							{

								if(next.isBlank/** || next.isIdle*/)
								{
									console.warn("isBlank",next.isBlank);
									if(i > 0)//检测左侧
									{
										let left = this._popArr[i - 1][j - n];
										if(left && !left.isBlank)
										{
											///从左侧移动一个下来
											this._popArr[i][j] = left;
											this._popArr[i - 1][j - n] = null;
											left.tagPt = egret.Point.create(i,j);
											result = true;
											break;
										}
									}

									//左侧检测不通过，检测右侧
									if(i < this._popArr.length - 1)
									{
										let right = this._popArr[i + 1][j - n];
										if(right && !right.isBlank)
										{
											///从左侧移动一个下来
											this._popArr[i][j] = right;
											
											this._popArr[i + 1][j - n] = null;
											right.tagPt = egret.Point.create(i,j);
											result = true;
											break;
										}
									}
									console.warn("上层没有可以给他提供pop的",i,j);
									//上层没有可以给他提供pop的
									let blankPop = PopPool.create();
									blankPop.isBlank = true;
									this._popArr[i][j] = blankPop;
									isBlank = true;
									break;
								}
								else
								{
									this._popArr[i][j] = next;
									this._popArr[i][j - n] = null;
									next.tagPt = egret.Point.create(i,j);
									result = true;
									break;
								}
							}
							else
							{
								if(i > 0)//检测左侧
								{
									let left = this._popArr[i - 1][j - n];
									if(left && !left.isBlank)
									{
										///从左侧移动一个下来
										this._popArr[i][j] = left;
										this._popArr[i - 1][j - n] = null;
										left.tagPt = egret.Point.create(i,j);
										result = true;
										break;
									}
								}

								//左侧检测不通过，检测右侧
								if(i < this._popArr.length - 1)
								{
									let right = this._popArr[i + 1][j - n];
									if(right && !right.isBlank)
									{
										///从左侧移动一个下来
										this._popArr[i][j] = right;
										
										this._popArr[i + 1][j - n] = null;
										right.tagPt = egret.Point.create(i,j);
										result = true;
										break;
									}
								}
							}
							console.warn("它上面没有",i,j,n);
							n++;
						}
					}
				}
			}
			return result;
		}

		/**检测三个，正上、左上、右上 */
		private checkSuperior():void
		{

		}

		private moveAll():void
		{
			for(let i = this._popArr.length - 1;i >= 0;i--)
			{
				let popCol = this._popArr[i];
				for(let j = popCol.length - 1;j >= 0;j--)
				{
					let pop = popCol[j];
					if(pop)
					{
						pop.move();
					}
				}
			}
		}

		/**生成新的pop */
		private createNewPop():boolean
		{
			//缺多少个，就创建多少个...
			let result = false;
			for(let i = this._popArr.length - 1;i >= 0;i--)
			{
				let popCol = this._popArr[i];
				for(let j = popCol.length - 1;j >= 0;j--)
				{
					let pop = popCol[j];
					if(pop == null)//它上面的都是空的
					{
						console.log("createNewPop:",i,j);
						let n = j + 1;
						while(n > 0)
						{
							n--;
							if(this._popArr[i][n])
							{
								continue;
							}

							let pop = PopPool.create();
							pop.type = this.random();
							this._popSp.addChild(pop);
							this.setPopPos(pop,i,n);
							pop.curPt = egret.Point.create(i,n - j - 1);
							pop.x = i*40;
							pop.y = (n - j - 1)*40;
							pop.tagPt = egret.Point.create(i,n);
							this._popArr[i][n] = pop;
						}
						result = true;
						break;
					}
				}
			}

			return result;
		}

		private setPopPos(pop:BasePop,x:number,y:number):void
		{
			pop.curPt = egret.Point.create(x,y);
			pop.x = x*40;
			pop.y = y*40;
			this._popArr[x][y] = pop;
		}

		private random():number
		{
			let result = Math.floor(Math.random()*this._types);
			console.log("random:",result);
			return result;
		}

		/**
		 * 销毁场景
		 *  */
		public dispose():void
		{
			this._gridArr = [];
			this._popArr = [];
			this._gridSp.removeChildren();
			this._popSp.removeChildren();
		}
	}
}